package com.xinzhitong.www.service.impl;

import com.xinzhitong.www.enumeration.GoodType;
import com.xinzhitong.www.exception.GoodException;
import com.xinzhitong.www.exception.TradeException;
import com.xinzhitong.www.exception.good.InvalidGoodException;
import com.xinzhitong.www.exception.good.OwnedGoodException;
import com.xinzhitong.www.exception.trade.MultiTradeException;
import com.xinzhitong.www.mapper.*;
import com.xinzhitong.www.pojo.Good;
import com.xinzhitong.www.pojo.Trade;
import com.xinzhitong.www.pojo.User;
import com.xinzhitong.www.service.PayService;
import com.xinzhitong.www.utils.PayUtil;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;

/**
 * 支付服务实现类
 *
 * @author 徐鑫
 */
@Service
@Transactional
public class PayServiceImpl implements PayService {

    @Resource
    GoodMapper goodMapper;

    @Resource
    BuyMapper buyMapper;

    @Resource
    SystemMessageMapper systemMessageMapper;

    @Resource
    CourseMapper courseMapper;

    @Resource
    TrainMapper trainMapper;

    @Resource
    QuestionBankMapper questionBankMapper;

    private static Map<GoodType, String> titleMap = new HashMap<>();
    private static Map<GoodType, String> interfaceMap = new HashMap<>();

    static {
        titleMap.put(GoodType.QUESTIONBANK, "题库购买成功");
        titleMap.put(GoodType.COURSE, "课程购买成功");
        titleMap.put(GoodType.TRAINCLASSTIME, "培训报名成功");
        interfaceMap.put(GoodType.QUESTIONBANK, "/questionBank/message");
        interfaceMap.put(GoodType.COURSE, "/course/message");
        interfaceMap.put(GoodType.TRAINCLASSTIME, "/train/trainSystemMessage");
    }

    @Override
    public String getParamsOfGoodOfId(Integer goodId, GoodType goodType) throws GoodException {
        Good good = goodMapper.selectGoodInfoById(goodId);
        //商品不存在
        if (good == null)
            throw new InvalidGoodException();
        Subject subject = SecurityUtils.getSubject();
        User user = (User) subject.getPrincipal();
        Trade trade = buyMapper.selectTradeByUsernameAndGoodId(user.getUsername(), goodId);
        //重复购买
        if (trade != null)
            throw new OwnedGoodException();
        //若为免费商品
        if (good.getPrice() == 0) {
            try {
                //创建免费的订单
                Trade tmp = new Trade();
                tmp.setGoodId(goodId);
                tmp.setGoodType(goodType);
                tmp.setUsername(user.getUsername());
                tmp.setTotalAmount(0d);
                tmp.setOutTradeNo(PayUtil.createOutTradeNo(user.getUsername(), goodId, goodType));
                record(tmp);
                //发货
            } catch (Exception e) {
                e.printStackTrace();
                throw new OwnedGoodException();
            }
            return null;
        }
        return PayUtil.getUrlParams(user.getUsername(), good.getId(), goodType, good.getPrice(), good.getName());
    }

    @Override
    public void record(Trade trade) throws TradeException {
        //添加订单失败
        if (buyMapper.insertTrade(trade) == 0)
            throw new MultiTradeException();
        //成功则发送系统消息
        String title = titleMap.get(trade.getGoodType());//标题
        String text = getText(trade);//正文
        String url = interfaceMap.get(trade.getGoodType());//查看详情链接
        url += "?id=" + trade.getGoodId();//添加参数
        systemMessageMapper.insertSystemMessage(trade.getUsername(), title, text, url);
    }

    /**
     * 根据订单获取系统消息正文
     *
     * @param trade 订单
     * @return 正文内容
     */
    private String getText(Trade trade) {
        String res = "您已成功购买";
        String goodName = "";
        switch (trade.getGoodType()) {
            case COURSE:
                goodName = courseMapper.selectIntroduction(trade.getGoodId()).getName();
                break;
            case TRAINCLASSTIME:
                goodName =
                        (String) trainMapper.selectTrainClassApplyInformation(trade.getGoodId()).get("trainClassName");
                break;
            case QUESTIONBANK:
                goodName = (String) questionBankMapper.selectQuestionBankById(trade.getGoodId()).get("name");
                break;
        }
        return res + "'" + goodName + "'";
    }

}
